#! /usr/bin/env python
# -*- coding: utf-8 -*-

from django.shortcuts import render, redirect, HttpResponse
from django.http import JsonResponse
from web.form.file import FolderModelForm, FileModelForm
from django.views.decorators.csrf import csrf_exempt
from web import models
from django.forms import model_to_dict
from utils.tencent.cos import delete_file, delete_file_list, get_cos_token
import json
from django.urls import reverse
from django.utils.http import urlquote


@csrf_exempt
def file(request, project_id):
    """文件列表"""
    # /file/ 根目录
    # /file/?folder=9 父目录为9
    parent_obj = None
    folder_id = request.GET.get('folder_id', '')
    if folder_id.isdecimal():
        parent_obj = models.FileRepository.objects.filter(id=folder_id,
                                                          file_type=2, project=request.tracer.project).first()

    # 查看页面
    if request.method == "GET":
        # 导航条
        breadcrumb_list = []
        parent = parent_obj
        while parent:
            # breadcrumb_list.insert(0, {'id': parent.id, 'name': parent.name})
            breadcrumb_list.insert(0, model_to_dict(parent, ['id', 'name']))
            parent = parent.parent

        # print(breadcrumb_list)
        # 获取当前目录下所有的文件/夹
        querryset = models.FileRepository.objects.filter(project=request.tracer.project)
        if parent_obj:
            # 进入目录
            file_obj_list = querryset.filter(parent=parent_obj).order_by('-file_type')
        else:
            # 根目录
            file_obj_list = querryset.filter(parent__isnull=True).order_by('-file_type')

        form = FolderModelForm(request, parent_obj)
        return render(request, 'file.html',
                      {'form': form,
                       'file_obj_list': file_obj_list,
                       'breadcrumb_list': breadcrumb_list,
                       'parent_obj': parent_obj})

    if request.method == "POST":
        # 添加文件夹 和 修改

        # 获取fid 空为新建
        fid = request.POST.get('fid', '')
        edit_obj = None
        if fid.isdecimal():
            edit_obj = models.FileRepository.objects.filter(id=int(fid), file_type=2, project=request.tracer.project).first()

        if edit_obj:
            form = FolderModelForm(request, parent_obj, data=request.POST, instance=edit_obj)
        else:
            form = FolderModelForm(request, parent_obj, data=request.POST)

        if form.is_valid():
            form.instance.project = request.tracer.project
            form.instance.update_user = request.tracer.user
            form.instance.parent = parent_obj
            form.save()
            # print('test')
            return JsonResponse({'status': True})

        return JsonResponse({'status': False, 'error': form.errors})


# /manage/1/file/delete/?fid=1
def file_delete(request, project_id):
    """删除文件"""
    fid = request.GET.get('fid')
    # 级联删除 删除数据库中的文件/夹
    del_obj = models.FileRepository.objects.filter(id=fid, project=request.tracer.project).first()

    if del_obj.file_type == 1:
        # pass # 删除文件（数据库文件删除， cos文件删除、空间归还）
        # 归还已使用空间
        request.tracer.project.use_space -= del_obj.file_size
        request.tracer.project.save()

        # cos 删除文件
        delete_file(request.tracer.project.bucket, del_obj.key, request.tracer.project.region)
    else:
        # pass # 删除文件夹
        total_size = 0 # 所有文件的size
        folder_list = [del_obj]
        key_list = []

        for folder in folder_list:
            child_list = models.FileRepository.objects.filter(project=request.tracer.project, parent=folder).order_by('-file_type')
            for child in child_list:
                if child.file_type == 2:
                    folder_list.append(child)
                else:
                    # 文件
                    total_size += child.file_size
                    # 删除文件
                    key_list.append({"Key": child.key})

        # cos 批量删除
        if key_list:
            delete_file_list(request.tracer.project.bucket, key_list)
            request.tracer.project.use_space -= total_size
            request.tracer.project.save()

    del_obj.delete()

    return JsonResponse({'status': True})


# cos token
@csrf_exempt
def cos_credential(request, project_id):
    # 获取前端传的json数据
    file_list = json.loads(request.body.decode('utf-8'))
    per_file_limit = request.tracer.price_policy.per_file_size * 1024 * 1024
    total_size = 0
    for item in file_list:
        # 单文件大小限制(M)
        if item['size'] > per_file_limit:
            return JsonResponse({'status': False, 'err': f"单文件超出{request.tracer.price_policy.per_file_size}M。"})
        total_size += item['size']
    # 容量限制：
    if request.tracer.project.use_space + total_size > request.tracer.price_policy.project_space *1024 *1024:
        return JsonResponse({'status': False, 'err': f"容量超出限制，请升级套餐。"})

    # 获取凭证
    bucket = request.tracer.project.bucket
    region = request.tracer.project.region

    data = get_cos_token(bucket, region)
    data['status'] = True

    return JsonResponse(data)


@csrf_exempt
def file_post(request, project_id):
    """将已上传的文件写入数据库"""
    # {'name': ['ss.png'],
    # 'file_size': ['14333'],
    # 'key': ['1586846485572_ss.png'],
    # 'file_path': ['15621186673-1586836726805-1253437544.cos.ap-chengdu.myqcloud.com/1586846485572_ss.png'],
    # 'parent': [''],
    # 'etag': ['"544ecf7087c2eb1200437c59ae1af7f6"']}>
    # print(request.POST)

    # 写入数据库
    form = FileModelForm(data=request.POST)

    if form.is_valid():
        # 通过.save()保存到数据库返回的instance对象 无法通过get_xx_display 获取中文显示
        # form.instance.file_type = 1
        # form.instance.project = request.tracer.project
        # form.instance.update_user = request.tracer.user
        # instance = form.save()

        # 更新已使用空间
        request.tracer.project.use_space += form.cleaned_data.get("file_size")
        request.tracer.project.save()

        # # 校验通过：数据写入到数据库, 可以使用get_xx_display
        data_dict = form.cleaned_data
        data_dict.pop('etag')
        data_dict.update({'project': request.tracer.project, 'file_type': 1, 'update_user': request.tracer.user})
        instance = models.FileRepository.objects.create(**data_dict)

        data = {
            'id': instance.id,
            'name': instance.name,
            'file_size': instance.file_size,
            'username': instance.update_user.username,
            'datetime': instance.update_datetime,
            'download_url': reverse('file_download', kwargs={"project_id": project_id, "file_id": instance.id})
        }
        return JsonResponse({'status': True, 'data': data})

    return JsonResponse({'status': False, 'data': form.errors})


def file_download(request, project_id, file_id):
    """ 下载文件"""

    import requests
    # 1. 找到文件; cos 获取文件内容
    file_obj = models.FileRepository.objects.filter(id=file_id, project=request.tracer.project).first()
    data = requests.get(file_obj.file_path).content
    # 2. 添加响应头
    # urlquote(file_obj.name) 支持中文显示
    res = HttpResponse(data, content_type="application/octet-stream")
    res["Content-Disposition"] = f"attachment; filename={urlquote(file_obj.name)}"

    return res

